package com.boot.notes.event;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionalEventListener;

/**
 * 注解式Event事件
 * 推荐使用，不用每个事件都去实现ApplicationListener类
 *
 * @Description: 自定义的Event事件监听类，交给spring管理
 * @Author: mkq
 * @Date: 2021/10/8 16:16
 **/
@Component
@Slf4j
public class AnnotationLister {

    /**
     * 如果要监听多个事件类型的发布，可以在@EventListener(classes = {RegisterEvent.class,OrderEvent.class})指定，
     * spring会多次调用此方法来处理多个事件。但是注意此时，方法参数不能有多个，否则会发生转换异常，
     * 可以将使用多个事件的父类作为唯一的方法参数来接收处理事件，但除非必要否则并不推荐监听多个事件的发布。
     * 可以2个方法同时监听同一个事件,并且优先级按照数字值小的先监听.
     * 不过发布者发布了一个事件,但是在有2个方法同时监听的时候这两个方法都会执行,只是执行顺序按照@Order中的值来决定
     *
     * @param event
     */
    @Async
    @EventListener(classes = {RegisterEvent.class})
    @Order(1)
    public void onAnnotationEvent_1(RegisterEvent event) {

        log.info("收到自定义的 RegisterEvent 事件了,优先级=1-------{}", event.getMessage());
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        log.info("收到自定义的 RegisterEvent 事件执行完了-------{}", event.getMessage());
    }


    @TransactionalEventListener(classes = {OrderEvent.class}, fallbackExecution = true)
    @Order(2)
    public void onAnnotationEvent_2(ApplicationEvent event) {
        OrderEvent oe = (OrderEvent) event;
        log.info("收到自定义的 OrderEvent 事件了,优先级=2-------{}", oe.getMessage());
//        try {
//            Thread.sleep(100);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        log.info("收到自定义的 OrderEvent 事件了,事件执行完了-------{}", oe.getMessage());
    }

}

